/*
 * Copyright (C) 2019 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specificlanguage governing permissions and
 * limitations under the License.
 *
 */

package probes

import (
	"fmt"
	"net/url"
	"strings"

	"github.com/skydive-project/skydive/api/types"
	"github.com/skydive-project/skydive/config"
)

// NormalizeBPFFilter returns a normalized BPF filter in order to exclude
// traffic generated by skydive itself
func NormalizeBPFFilter(capture *types.Capture) string {
	var exclude []string

	// analyzers
	sas, err := config.GetAnalyzerServiceAddresses()
	if err == nil {
		for _, sa := range sas {
			exclude = append(exclude, fmt.Sprintf("not (host %s and port %d)", sa.Addr, sa.Port))
		}
	}

	// etcd
	for _, s := range config.GetEtcdServerAddrs() {
		if u, err := url.Parse(s); err != nil {
			exclude = append(exclude, fmt.Sprintf("not (host %s and port %s)", u.Host, u.Port()))
		}
	}

	// target
	if capture.Target != "" {
		s := strings.Split(capture.Target, ":")
		if s[1] != "0" {
			exclude = append(exclude, fmt.Sprintf("not (host %s and port %s)", s[0], s[1]))
		} else {
			exclude = append(exclude, fmt.Sprintf("not host %s", s[0]))
		}
	}

	excluded := strings.Join(exclude, " and ")

	if capture.BPFFilter != "" {
		return fmt.Sprintf("(%s) and %s", capture.BPFFilter, excluded)
	}
	return excluded
}
